# 官方
import os
import re
import time

# 第三方
import openpyxl
# from tqdm import tqdm

# 自定义


def get_rows(ws):
    """
    获取xlsx转换为lua配置表得行范围
    :param ws: workSheet
    :return: min_row[int], max_row[int]
    """
    row_index = str(ws.cell(2, 1).value or "").split("-")
    min_row = int(row_index[0] or 5)
    max_row = int(
        row_index[1]) if len(row_index) == 2 and row_index[1] else ws.max_row
    return min_row, max_row


def desc2number(sign, txt):
    """
    描述转数字

    Args:
        sign (str): 符号
        txt (str): 
    Returns:
        int, float: 
        str: 'f' 或 'p'
    """
    if '%' in txt:
        data_type = 'p'
        value = float(txt.rstrip("%")) / 100
    else:
        data_type = 'f'
        value = float(txt)

    if value == int(value):
        value = int(value)

    if sign == "-":
        value = value * -1

    return value, data_type


def get_attrs_and_desc(txt):
    desc = txt
    attrs = {}
    i = 0
    while True:
        match = re.search("([^n，、]+?)([\+\-])(([\d\.%\/]+)|([\d\.%\/]+)$)",
                          desc)
        if not match:
            break
        i += 1

        if '/' in str(match.group(3)):
            # 多级
            tmp = match.group(3).split('/')
            value = []
            for v in tmp:
                elem, data_type = desc2number(match.group(2), v)
                value.append(elem)
                data_type = f'{data_type}s'
        else:
            value, data_type = desc2number(match.group(2), match.group(3))
        
        attrs[match.group(1)] = value
        desc = desc.replace(f'{match.group(2)}{match.group(3)}',
                            f'{match.group(2)}<{data_type}{i}>', 1)
        desc = desc.replace("\n", "|n")
        desc = desc.replace("，", "|n")
        desc = desc.replace("、", "|n")

    desc = f"'{desc}'"

    return attrs, desc


def get_cell_data(ws, row, col):
    res = ''
    data = ws.cell(row, col).value
    if not data:
        return res

    data_type = ws.cell(2, col).value
    if not data_type:
        print(f"[ERR] 第{col}列数据 data_type is None!")
        return res

    if data_type == "s":
        res = f'"{data}"'
    elif data_type == "i":
        res = f'{int(data)}'
    elif data_type == "f":
        res = f'{float(data)}'
    elif data_type == "x":
        res = data

    return res


def get_arch_script(attrs):
    code = "\n\n-- arch"
    code += "\n---@param p Player"
    code += "\n---@param isAdd boolean"
    code += "\n---@param amt integer"
    code += "\nfunction pack.onSwitch(p, isAdd, amt)"
    tmp = ["", "", ""]
    i = 0
    for attr, value in attrs.items():
        i += 1
        if type(value) == list:
            # 多级
            tmp[0] += f"\n\tlocal v{i} = pack.data{i}[amt]"
        else:
            tmp[0] += f"\n\tlocal v{i} = pack.data{i} * (amt or 1)"
        
        tmp[1] += f"\n\t\tv{i} = v{i} * -1"
        tmp[2] += f"\n\t\t['{attr}'] = v{i},"

    if tmp[0]:
        code += tmp[0]
        code += "\n\n\tif not isAdd then"
        code += tmp[1]
        code += "\n\tend"
        code += "\n\n\tp:mod_attr({"
        code += tmp[2]
        code += f"\n\t}}, '{module}')"
    else:
        code += "\n\t"
    code += "\nend"
    code += "\n\n"
    code += "\n-- ---@return integer"
    code += "\n-- function pack.getValue(p)"
    code += "\n"
    code += "\n-- end"
    code += "\n\n"
    code += "\n-- function pack.setValue(p, v)"
    code += "\n"
    code += "\n-- end"
    code += "\n\n"
    code += "\n-- function pack.tracking(p)"
    code += "\n"
    code += "\n-- end"
    code += "\n\n"
    code += "\nreturn pack\n"
    return code


def write(ws):
    min_row, max_row = get_rows(ws)
    max_col = ws.max_column
    # print(f"min_row: {min_row}, max_row: {max_row}")
    for row in range(min_row, max_row + 1):
        sid = ws.cell(row, 2).value
        # # 数字型id
        # file_path = folder + "/" + f"{module}{sid:03}.lua"
        # 下划线型id
        file_path = folder + "/" + f"{module}_{sid}.lua"
        code = "-- config\nlocal pack = {\n"
        for col in range(2, max_col + 1):
            # 空行
            if ws.cell(2, col).value == 'wrap':
                code += '\n'
                continue

            # 字段名为空则忽略
            key = ws.cell(3, col).value
            if not key:
                continue

            if key == 'desc':
                attrs, val = get_attrs_and_desc(ws.cell(row, col).value)
                if val:
                    code += f"\t{key} = {val},\n"

                i = 0
                for value in attrs.values():
                    i += 1
                    j = 6  # 一行几个data
                    if i % j == 1:
                        code += "\t"
                    if type(value) == list:
                        value = str(value).replace("[", "{")
                        value = str(value).replace("]", "}")
                    code += f"data{i} = {value},"
                    if i % j == 0 or i == len(attrs.values()):
                        code += "\n"
                    else:
                        code += " "

                break

            val = get_cell_data(ws, row, col)
            if val:
                code += f"\t{key} = {val},\n"

        code += "}\n"
        code += get_arch_script(attrs)

        with open(file_path, "w", encoding="utf-8") as f:
            f.write(code)


if __name__ == "__main__":
    src_path = input("工作簿路径：") or r"C:\Users\chenhao_wu\Desktop\黑咒3.xlsx"

    src_wb = openpyxl.load_workbook(src_path, data_only=True)
    src_ws = src_wb.active

    # 可选
    # module_folder = "stageTreasure/"
    module_folder = ""

    module = src_ws.cell(1, 1).value
    module_name = src_ws.title

    # 输出的脚本文件目录
    # folder = r"D:\war3_workspace\heizhou\script\game\__data\skills" + "/" + module
    folder = r"D:\war3_workspace\heizhou\script\game\__data\bonus" + "/" + module_folder + module

    if not os.path.exists(folder):
        os.makedirs(folder)

    write(src_ws)
